import { getElWidth, findMinNumberIndex } from "./utils";

/*
  Lazyload
  el.offsetTop > pageEl.scrollTop + pageEl.offsetHeight ? 'show' : 'lazy'
*/

class Waterfall {
  /** @type {number} 行数  */
  columns;
  /** @type {number} 边距 */
  margin;
  /** @type {number[]} 控制高度的数组  */
  heightArr = [];

  constructor({ columns = 2, margin = 10 }) {
    this.columns = columns;
    this.margin = margin;
  }

  init() {
    const ctx = this;
    return {
      bind: this.bindVm.bind(ctx),
    };
  }

  async bindVm(el, binding, vNode) {
    const { dataList } = binding.value,
      { style } = vNode.data;
    await this._createWfItems(el, style, dataList);

    el.addEventListener("scroll", this.onWfScroll.bind(this), false);
  }
  /** 确认第一行的元素 */
  _createWfItems(el, styles, dataList) {
    this._setElStyles(el, styles);
    this._createItems(el, dataList);
  }
  /** 给el绑定样式类 */
  _setElStyles(el, styles) {
    Object.getOwnPropertyNames(styles).forEach((styleKey) => {
      el.style[styleKey] = styles[styleKey];
    });
  }
  /**
   * 创建元素
   * @param {HTMLElement} el
   * @param {[]} dataList
   * */
  _createItems(
    el,
    dataList = []
    // { src }, // dataIdx = 0
  ) {
    el.style.visibility = "hidden";

    dataList.forEach(({ src }) => {
      const itemEl = document.createElement("div");
      const elWdith = getElWidth(el, this.columns, this.margin);
      itemEl.className = "waterfall-item";

      itemEl.style.margin = this.margin + "px";
      itemEl.style.width = elWdith + "px";

      const _img = new Image();

      _img.src = src;
      _img.alt = "";

      _img.loading = "lazy";

      _img.onload = () => {
        itemEl.appendChild(_img);
        el.appendChild(itemEl);
      };
    });

    setTimeout(() => {
      dataList.forEach((data, dataIdx) => {
        const itemEl = el.querySelectorAll(".waterfall-item")[dataIdx],
          elWdith = getElWidth(el, this.columns, this.margin);

        /** set top */
        if (dataIdx < this.columns) {
          itemEl.style.top = "0px";
          itemEl.style.left =
            (dataIdx + 1) * this.margin + dataIdx * elWdith + "px";
          if (this.heightArr.length < this.columns) {
            this.heightArr.push(itemEl.offsetHeight);
          }
        } else {
          const minIdx = findMinNumberIndex(this.heightArr);
          if (minIdx === -1) {
            return;
          }
          itemEl.style.top = this.heightArr[minIdx] + this.margin + "px";
          itemEl.style.left =
            (minIdx + 1) * this.margin + minIdx * elWdith + "px";
          this.heightArr[minIdx] += itemEl.clientHeight + this.margin;
        }
      });

      el.style.visibility = "visible";
    }, 300);
  }
  /** 监听容器滚动 */
  onWfScroll(e) {
    console.log(e);
  }
}

export default Waterfall;
